package com.aube.control.player;

import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 多镜头的丢帧检测逻辑
 * 如果丢帧过于频繁达到阈值,说明cpu负载太高,不适合多镜头播放,此时会只播放当前选中的那路多镜头并暂停其他
 * Created by huyaonan on 16/9/20.
 */
public class MultiVideoBalanceAdapter {

    private static MultiVideoBalanceAdapter mInstance;
    private OnVideoBalanceCallBack mCallBack;
    private HashMap<String, Integer> mFrameDropStates;
    private HashMap<String, Long> mFrameDropTimestamps;
    private static final int MAX_FRAMEDROP_COUNT = 5;

    private AtomicBoolean mBalanceOn = new AtomicBoolean(false);

    private MultiVideoBalanceAdapter() {}

    public static synchronized MultiVideoBalanceAdapter getInstance() {
        if(mInstance == null)
            mInstance = new MultiVideoBalanceAdapter();
        return mInstance;
    }

    public void reset() {
        if(!AbstractVideoHelper.ENABLE_VIDEO_BALANCE)
            return;
        mBalanceOn.set(false);
        if(mFrameDropStates == null)
            mFrameDropStates = new HashMap<>();
        else
            mFrameDropStates.clear();

        if(mFrameDropTimestamps == null)
            mFrameDropTimestamps = new HashMap<>();
        else
            mFrameDropTimestamps.clear();
    }

    public boolean isLowExperience() {
        if(!AbstractVideoHelper.ENABLE_VIDEO_BALANCE)
            return false;
        return mBalanceOn.get();
    }

    public synchronized void report(String id) {
        if(!AbstractVideoHelper.ENABLE_VIDEO_BALANCE)
            return;

        if(mBalanceOn.get())
            return;

        int maxcount = 0;
        if(mFrameDropStates == null)
            mFrameDropStates = new HashMap<>();
        if(mFrameDropTimestamps == null)
            mFrameDropTimestamps = new HashMap<>();
        if(mFrameDropStates.containsKey(id)) {
            long current = System.currentTimeMillis();
            if(mFrameDropTimestamps.containsKey(id))
                current = mFrameDropTimestamps.get(id);
            //4000ms内的卡顿,算一次
            if(current <= System.currentTimeMillis() + 4000) {
                maxcount = mFrameDropStates.get(id) + 1;
                mFrameDropStates.put(id, maxcount);
            }
        } else {
            mFrameDropStates.put(id, 1);
            mFrameDropTimestamps.put(id, System.currentTimeMillis());
        }

        if(mFrameDropStates.size() >= 2 && maxcount >= MAX_FRAMEDROP_COUNT) {
            mBalanceOn.set(true);

            if(mCallBack != null)
                mCallBack.pauseAndWarn();
        }
    }

    /**
     * 进入下一组多镜头的时候, 重新开始统计
     */
    public void recount() {
        if(!AbstractVideoHelper.ENABLE_VIDEO_BALANCE)
            return;

        mBalanceOn.set(false);

        if(mFrameDropStates == null)
            mFrameDropStates = new HashMap<>();
        else
            mFrameDropStates.clear();

        if(mFrameDropTimestamps == null)
            mFrameDropTimestamps = new HashMap<>();
        else
            mFrameDropTimestamps.clear();
    }

    public void registBalanceCallBack(OnVideoBalanceCallBack callBack) {
        this.mCallBack = callBack;
    }

    public interface OnVideoBalanceCallBack {
        public void pauseAndWarn();
    }

}
